// import mqtt from 'mqtt'
import * as mqtt from "mqtt/dist/mqtt.js";

// 声明mqtt的options数据包类型
export interface MqttconnecOption extends mqtt.IClientOptions { }

// 为方便外部组件处理message,声明消息回调方法类型
export declare type OnMessageFun = (topic: string, payload: Buffer) => void

// 声明mqtt主题配置
interface Topic {
  topic: string | string[]
  qos: 0 | 1 | 2
}


export class Mqtt {
  mqclient!: mqtt.MqttClient //mq连接实例
  brokerHost: string //连接地址
  // brokerPort: number //这里可以自定义端口,看自己怎么定义
  subscribeTopics: Array<Topic> // 订阅的主题数组
  subscribeCallbacks: Map<string, OnMessageFun> //订阅消息的回调

  constructor(host?: string | any, port?: number | any) {
    this.brokerHost = host
    // this.brokerPort = port

    this.subscribeTopics = new Array<Topic>()
    this.subscribeCallbacks = new Map<string, OnMessageFun>()
  }

  /**
   *  订阅主题
   */
  //  @ts-ignore
  public subscribe(topic: string | string[], qos: 0 | 1 | 2): void {
    this.subscribeTopics.push({ topic, qos })
    if (this.is_connect()) {
      this.mqclient.subscribe(topic, qos, error => {
        if (!error) {
          console.log(topic)
          console.log('success')
        } else {
          console.log('fail')
        }
      })
    }
  }
  public unsubscribe(topic: string | string[], qos: 0 | 1 | 2): void {

    if (this.is_connect()) {
      this.mqclient.unsubscribe(topic, qos, error => {
        if (!error) {
          console.log(topic)
          console.log('unsubscribe success')
        } else {
          console.log('fail')
        }
      })
    }
  }

  /**
   * 判断是否已经连接mq
   */

  public is_connect(): boolean {
    return this.mqclient.connected === true
  }

  /**
   *  消息数据回调方法
   */

  public message_callback(topicPatten: string, cb: OnMessageFun) {
    this.subscribeCallbacks.set(topicPatten, cb)
  }

  /**
   * @description: 连接方法
   * @param {MqttconnecOption} options:mqtt连接参数体
   * @return {*}
   */

  public connect(options: MqttconnecOption) {
    this.mqclient = mqtt.connect(`${this.brokerHost}`, options)

    // 连接
    this.mqclient.on('connect', () => {
      console.log('Mqtt Connection succeeded!')
      for (let i = 0; i < this.subscribeTopics.length; i++) {
        const el = this.subscribeTopics[i]
        this.mqclient.subscribe(el.topic, { qos: el.qos }, error => {
          if (!error) {
            console.log('success')
          } else {
            console.log('fail')
          }
        })
      }
    })
    // 消息
    this.mqclient.on('message', (topic: string, payload: Buffer) => {
      console.log('Connection message!')
      // this.mqclient
      this.subscribeCallbacks.forEach((val, key) => {
        if (topic.indexOf(key) !== -1) {
          val(topic, payload)
        }
      })
    })

    // 重连
    this.mqclient.on('reconnect', () => {
      console.log('reconnect')
    })

    // 错误
    this.mqclient.on('error', (err: Error) => {
      console.log('Connection error!')
      console.log('错误信息' + err)
    })

    // 离线
    this.mqclient.on('offline', (err: Error) => {
      console.log('offline')
    })
  }
  /**
   * @description: 数据推送  我们数据推送采用http，因为中间要翻译
   * @param {string} topic
   * @param {string} message
   * @param {0} qos
   * @return {*}
   */
  // public publish(topic: string, message: string, qos: 0 | 1 | 2) {
  //   this.mqclient.publish(topic, message, { qos: qos, retain: false })
  // }
}
